%
% Distortion Specification Post Processing 
%

% Initialize Variables
clear
symbolRate=125e6;                               % symbol rate
dataFile=input('Data file name: ','s')

% Generate test pattern symbol sequence

scramblerSequence=ones(1,2047);
for i=12:2047
  scramblerSequence(i)=mod(scramblerSequence(i-11) + scramblerSequence(i-9),2);
end

for i=1:2047
  temp=scramblerSequence(mod(i-1,2047)+1) + ...
      2*mod(scramblerSequence(mod(i-2,2047)+1) + scramblerSequence(mod(i-5,2047)+1),2) + ...
      4*mod(scramblerSequence(mod(i-3,2047)+1) + scramblerSequence(mod(i-5,2047)+1),2);
  switch temp
    case 0,
      testPattern(i)=0;
    case 1,
      testPattern(i)=1;
    case 2,
      testPattern(i)=2;
    case 3,
      testPattern(i)=-1;
    case 4,
      testPattern(i)=0;
    case 5,
      testPattern(i)=1;
    case 6,
      testPattern(i)=-2;
    case 7,
      testPattern(i)=-1;
  end
end
  


% Input data file
fid=fopen(dataFile,'r');
sampledData=fscanf(fid,'%f');
fclose(fid);
sampledData=sampledData.';

if (length(sampledData) < 2047)
  error('Must have 2047 consecutive samples for processing');
elseif (length(sampledData) > 2047)
  fprintf(1,'\n Warning - only using first 2047 samples in data file');
  sampledData=sampledData(1:2047);  
end


% Fit a sine wave to the data and temporarily remove it to yield processed data

options=foptions;
options(1)=0;
options(2)=1e-8;
options(3)=1e-8;
options(14)=2000;
gradfun=zeros(0);
P=fmins('sinefit',[2.0 0 125/6.],options,gradfun,sampledData,symbolRate);

P

processedData=sampledData - ...
    P(1)*sin(2*pi*(P(3)*1e6*[0:2046]/symbolRate + P(2)*1e-9*symbolRate));



% LMS Canceller

numberCoeff=70;  % Number of coefficients in canceller
coefficients=zeros(1,numberCoeff);
delayLine=testPattern;

% Align data in delayLine to sampled data pattern
temp=xcorr(processedData,delayLine);
index=find(abs(temp)==max(abs(temp)));
index=mod(mod(length(processedData) - index(1),2047)+numberCoeff-10,2047);
delayLine=[delayLine((end-index):end) delayLine(1:(end-index-1))];


% Compute coefficients that minimize squared error in cyclic block

for i=1:2047
  X(i,:)=delayLine(mod([0:(numberCoeff-1)]+i-1,2047)+1);
end
coefficients=(inv(X.' * X)*(processedData*X).').';


  
% Canceller
for i=1:2047
  err(i)=processedData(i) - sum(delayLine(1+mod((i-1):(i+numberCoeff-2),2047)).*coefficients); 
end

% Add back temporarily removed sine wave

err=err+P(1)*sin(2*pi*(P(3)*1e6*[0:2046]./symbolRate + P(2)*1e-9*symbolRate));


% Re-fit sine wave and do a final removal 

options=foptions;
options(1)=0;
options(2)=1e-12;
options(3)=1e-12;
options(14)=10000;
gradfun=zeros(0);
P=fmins('sinefit',[2.0 0 125/6.],options,gradfun,err,symbolRate);

P

processedData=sampledData - ...
    P(1)*sin(2*pi*(P(3)*1e6*[0:2046]/symbolRate + P(2)*1e-9*symbolRate));


% Compute coefficients that minimize squared error in cyclic block

coefficients=(inv(X.' * X)*(processedData*X).').';


  
% Canceller
for i=1:2047
  err(i)=processedData(i) - sum(delayLine(1+mod((i-1):(i+numberCoeff-2),2047)).*coefficients); 
end

% SNR Calculation
signal=0.5;
noise=mean(err.^2);

SNR=10*log10(signal./noise);

% Output Peak Distortion

peakDistortion=max(abs(err))
